/*
 * Copyright (c) 2025 李伟国
 * SQL-API is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan
 * PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *          http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY
 * KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
 * NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */
package com.moyu.sql.business.service.impl;

import com.moyu.sql.business.constant.SelectTypeEnum;
import com.moyu.sql.business.entity.MoyuSql;
import com.moyu.sql.business.service.IMoyuSqlExecuteService;
import com.moyu.sql.business.service.IMoyuSqlService;
import com.moyu.sql.business.utils.PageUtils;
import com.moyu.sql.core.engine.MoyuSqlSession;
import jakarta.annotation.Resource;
import org.apache.ibatis.mapping.SqlCommandType;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.util.List;
import java.util.Map;

@Service
public class MoyuSqlExecuteServiceImpl implements IMoyuSqlExecuteService {

    @Resource
    private IMoyuSqlService moyuSqlService;

    @Resource
    private MoyuSqlSession sqlSession;

    /**
     * 执行sql
     * 查询SQL返回列表或Map对象
     * 其余类型的sql返回影响的行数
     *
     * @param sqlId     sqlId
     * @param paramsMap 参数
     * @return 执行结果
     */
    @Override
    public Object execute(String sqlId, Map<String, Object> paramsMap) {
        MoyuSql sql = moyuSqlService.getById(sqlId);
        if(ObjectUtils.isEmpty(sql)){
            return null;
        }
        return switch (sql.getSqlCommandType()) {
            case SELECT -> {
                if (SelectTypeEnum.LIST.equals(sql.getSelectType())) {
                    yield sqlSession.selectList(sqlId, paramsMap);
                }
                else if (SelectTypeEnum.PAGE.equals(sql.getSelectType())) {
                    PageUtils.startPage();
                    List<Object> objects = sqlSession.selectList(sqlId, paramsMap);
                    yield PageUtils.getPageInfo(objects);
                }
                List<Object> objects = sqlSession.selectList(sqlId, paramsMap);
                if (CollectionUtils.isEmpty(objects)) {
                    yield null;
                } else {
                    int safeSearch = objects.size();
                    if(safeSearch > 1){
                        Map<String, Object> map = (Map<String, Object>) objects.get(0);
                        map.put("$noSafe$", safeSearch);
                        yield map;
                    }
                    yield objects.get(0);
                }

            }
            case INSERT -> sqlSession.insert(sqlId, paramsMap);
            case UPDATE -> sqlSession.update(sqlId, paramsMap);
            case DELETE -> sqlSession.delete(sqlId, paramsMap);
            default -> null;
        };
    }

    /**
     * 在系统启动后添加所有可用映射
     */
    @Async
    @Override
    public void addAllMappedStatement() {
        List<MoyuSql> list = moyuSqlService.list();
        if(ObjectUtils.isEmpty(list)){
            return;
        }
        for (MoyuSql sql : list) {
            SqlCommandType sqlCommandType = sql.getSqlCommandType();
            if(sqlCommandType == null){
                continue;
            }
            String sqlTemplate = sql.getSqlTemplate();
            if(ObjectUtils.isEmpty(sqlTemplate)){
                continue;
            }
            String sqlId = sql.getSqlId();
            if(ObjectUtils.isEmpty(sqlId)){
                continue;
            }
            sqlSession.addMappedStatement(sqlId, sqlTemplate, sqlCommandType);
        }
    }
}
